###########################################################################
#	$Id: conceptStorage.p 43 2009-07-13 10:07:20Z donbeave $
###########################################################################

@CLASS
conceptStorage

@USE
pf/types/pfClass.p
labour/tests/labourAssert.p
concept/converters/conceptFieldConverterBase.p

@BASE
pfClass

@OPTIONS
locals

@auto[]
  $self._CONVERTERS[^hash::create[]]

#----- Static -----

@getIntConverter[]
  ^if(!($_CONVERTERS.int is conceptFieldConverter)){
    $_CONVERTERS.int[^conceptFieldConverterBase::create[
      $.type[int]
      $.defaultValue(0)
    ]]
  }
  $result[$_CONVERTERS.int]

@getDoubleConverter[]
  ^if(!($_CONVERTERS.double is conceptFieldConverter)){
    $_CONVERTERS.double[^conceptFieldConverterBase::create[
      $.type[double]
      $.defaultValue(0.00)
    ]]
  }
  $result[$_CONVERTERS.double]

@getBoolConverter[]
  ^if(!($_CONVERTERS.bool is conceptFieldConverter)){
    $_CONVERTERS.bool[^conceptFieldConverterBase::create[
      $.type[bool]
      $.defaultValue(false)
    ]]
  }
  $result[$_CONVERTERS.bool]

#----- Constructor -----

@create[hshOptions]
## hshOptions.concept
## hshOptions.conceptOptions
## hshOptions.sharedLocales(true/false)
  ^cleanMethodArgument[hshOptions]

  $self._createOptions[$hshOptions]

  ^if(def $hshOptions.concept && $hshOptions.concept is conceptModule){
    $self._concept[$hshOptions.concept]
  }{
     $self._concept[]
   }

  $self._itemsClasses[
    $.Locales[
      $.file[concept/models/conceptLocaleItem.p]
      $.class[conceptLocaleItem]
    ]
    $.Objects[
      $.file[concept/models/conceptObjectItem.p]
      $.class[conceptObjectItem]
    ]
    $.ObjectsTexts[
      $.file[concept/models/conceptObjectTextItem.p]
      $.class[conceptObjectTextItem]
    ]
    $.ObjectsTypes[
      $.file[concept/models/conceptObjectTypeItem.p]
      $.class[conceptObjectTypeItem]
    ]
    $.Blocks[
      $.file[concept/models/conceptBlockItem.p]
      $.class[conceptBlockItem]
    ]
    $.DataTypes[
      $.file[concept/models/conceptDataTypeItem.p]
      $.class[conceptDataTypeItem]
    ]
    $.Processes[
      $.file[concept/models/conceptProcessItem.p]
      $.class[conceptProcessItem]
    ]
  ]

  $self._converters[
    $.Locales[
      $.SortOrder[^getIntConverter[]]
    ]
    $.Objects[
      $.SortOrder[^getIntConverter[]]
    ]
    $.ObjectsTypes[
      $.SortOrder[^getIntConverter[]]
      $.IsFake[^getBoolConverter[]]
    ]
    $.ObjectsTexts[
      $.IsPublished[^getBoolConverter[]]
    ]
    $.Blocks[
      $.IsPublished[^getBoolConverter[]]
      $.IsShared[^getBoolConverter[]]
      $.IsParsedManual[^getBoolConverter[]]
      $.IsNotEmpty[^getBoolConverter[]]
    ]
    $.DataTypes[
      $.SortOrder[^getIntConverter[]]
    ]
    $.Processes[
      $.SortOrder[^getIntConverter[]]
    ]
  ]

  $self._isLocalesLoaded(false)
  $self._isObjectsTypesLoaded(false)
  $self._isDataTypesLoaded(false)

  $self._sharedLocales(^hshOptions.sharedLocales.bool(true))

  $self._isReleased(true)

#----- Public -----

@addField[strTableName;strFieldName]
  ^_abstractMethod[]

@getFieldConverter[strTableName;strFieldName]
  ^labourAssert:required[strTableName;string]
  ^labourAssert:required[strFieldName;string]

  ^if($self._converters.[$strTableName]){
    $result[$self._converters.[$strTableName].[$strFieldName]]
  }{
     $result[]
   }

@setFieldConverter[strTableName;strFieldName;objConverter]
  ^labourAssert:required[strTableName;string]
  ^labourAssert:required[strFieldName;string]
  ^labourAssert:required[objConverter;conceptFieldConverter]

  $self._converters.[$strTableName].[$strFieldName][$objConverter]

@isReleased[]
  $result($self._isReleased)

@setRelease[blnRelease]
  ^labourAssert:required[blnRelease;bool]
  $result[]
  $self._isReleased($blnRelease)

@isUseSharedLocales[]
  $result($self._sharedLocales)

@isTreeBlocksSupported[]
  $result(^CONCEPT.isTreeBlocksSupported[])

@setLocalizedData[objItem;altData;objLocale]
  ^_abstractMethod[]

@loadLocales[]
  ^_abstractMethod[]

@loadObjectsTypes[]
  ^_abstractMethod[]

@loadDataTypes[]
  ^_abstractMethod[]

@getLocales[]
  ^_abstractMethod[]

@getLocaleByID[intID]
  ^_abstractMethod[]

@getLocaleByLanguage[strLang]
  ^_abstractMethod[]

@getTemporaryObject[strUID]
  ^_abstractMethod[]

@getRootObjects[hshOptions]
  ^_abstractMethod[]

@getObjectByID[intID]
  ^_abstractMethod[]

@getObjectsByType[objType;hshOptions]
  ^_abstractMethod[]

@getObjectChildren[objItem;hshOptions]
  ^_abstractMethod[]

@getObjectParent[objItem]
  ^_abstractMethod[]

@loadObjectsLocalizedData[altData]
  ^_abstractMethod[]

@getObjectLocalizedData[objItem;objLocale]
  ^_abstractMethod[]

@getObjectsTypes[]
  ^_abstractMethod[]

@getObjectTypeByID[intID]
  ^_abstractMethod[]

@getObjectTypeByName[strName]
  ^_abstractMethod[]

@createObject[objType;altData;altLocale]
  ^pfAssert:isTrue($objType is conceptObjectTypeItem || (def $objType && $objType is string))[Object type is wrong (CLASS_NAME: $objType.CLASS_NAME).]

  ^if($objType is string){
    $objType[^getObjectTypeByName[$objType]]
  }

  $result[^_createObjectItem[
    $.ID(0)
    $.SortOrder(0)
    $.TypeID($objType.ID)
    $.ParentID(0)
    $.ChildsCount(0)
#TODO добавить поддержку дополнительных полей
  ]]

  ^if(def $altData){
    ^result.setData[$altData;$altLocale]
  }

@createObjectText[altData;objItem;objLocale]
  ^labourAssert:required[objItem;conceptObjectItem]

  ^if(def $objLocale){
    ^labourAssert:required[objLocale;conceptLocaleItem]
  }

# если в altData строка, то воспринимаем ее как имя
  ^if($altData is string){
    $hData[
      $.Name[$altData]
    ]
  }{
    ^labourAssert:required[altData;hash]

    ^if(!def $altData.Name){
      ^pfAssert:fail[Required option "^$.Name" not specified.]
    }

    $hData[
      $.Name[$altData.Name]
    ]

    ^if($additionalTextsFields){
      ^additionalTextsFields.menu{
        ^hData.add[
          $.[$additionalTextsFields.field][$altData.[$additionalTextsFields.field]]
        ]
      }
    }
  }

  ^hData.add[
    $.IsPublished(false)
    $.ObjectID(0)
    $.LocaleID(^if(def $objLocale){$objLocale.ID}{$defaultLocale.ID})
  ]

  $result[^_createObjectTextItem[$hData;$objItem]]

#----- Private -----

@_createBaseItem[strClassify;hshData]
  ^use[$self._itemsClasses.[$strClassify].file]
  $sClassName[$self._itemsClasses.[$strClassify].class]

  ^if(!$self._itemsClasses.[$strClassify].hasFactory){
    ^use[$self._itemsClasses.[$strClassify].file]

    ^process{
      ^$self._itemsClasses.[$strClassify].factory[^$${self._itemsClasses.[$strClassify].class}:factory]
    }

    $self._itemsClasses.[$strClassify].hasFactory(true)
  }

  $jFactory[$self._itemsClasses.[$strClassify].factory]

  ^jFactory[$hshData][
    $.classify[$strClassify]
    $.storage[$self]
  ]

@_createLocaleItem[hshData]
  $result[^_createBaseItem[Locales;$hshData]]

@_createObjectItem[hshData]
  $result[^_createBaseItem[Objects;$hshData]]

@_createObjectTypeItem[hshData]
  $result[^_createBaseItem[ObjectsTypes;$hshData]]

@_createObjectTextItem[hshData;objItem]
  $result[^_createBaseItem[ObjectsTexts;$hshData]]

@_createBlockItem[hshData]
  $result[^_createBaseItem[Blocks;$hshData]]

@_createDataTypeItem[hshData]
  $result[^_createBaseItem[DataTypes;$hshData]]

@_createProcessItem[hshData]
  $result[^_createBaseItem[Processes;$hshData]]

#----- Properties -----

@GET_CONCEPT[]
  ^if(!def $self._concept){
    $self._concept[^conceptFactory[$_createOptions.conceptOptions]]
  }
  $result[$_concept]

@GET_DATA_MANAGER[]
  $result[$CONCEPT.DATA_MANAGER]

@SET_defaultLocale[objLocale]
  ^labourAssert:required[objLocale;conceptLocaleItem]

  $self._defaultLocale[$objLocale]

@GET_defaultLocale[]
  ^if(!def $self._defaultLocale){
    $oLocales[^getLocales[]]
    $self._defaultLocale[^oLocales.at(0)]
  }
  $result[$self._defaultLocale]

@GET_additionalObjectsFields[]
  ^_abstractMethod[]

@GET_additionalTextsFields[]
  ^_abstractMethod[]

#----- Fabriques -----

@conceptFactory[hshOptions]
  ^use[concept/conceptModule.p]
  $result[^conceptModule::create[$hshOptions]]
